home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / tsrfil10 / tsrbase.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-08  |  12.3 KB  |  384 lines

  1. // Written by Scott Hall of the U. of Missouri - Columbia, USA
  2.  
  3. // if file operations are used in tsr, you MUST be in compact, large, or
  4. // huge memory model for the getdta() and setdta() functions!!!
  5.  
  6. #pragma -mc                             // force compact memory model
  7.  
  8. #include <dos.h>
  9. #include <conio.h>
  10. #include <string.h>
  11. #include <io.h>
  12. #include <fcntl.h>
  13.  
  14. #define VIDEOMEMORY_COLOR 0xB8000000L   // needed for direct screen writes
  15. #define VIDEOBASE_COLOR 0xB800          // needed for movedata (screensaves)
  16. #define VIDEOMEMORY_MONO 0xB0000000L
  17. #define VIDEOBASE_MONO 0xB000
  18.  
  19. // prototypes of functions
  20.  
  21. // interrupt vectors
  22. void    interrupt int_5(void);          // front door to tsr (print screen)
  23. void    interrupt int_9(void);          // front door to tsr (key hit)
  24. void    interrupt (*old_int9)(void);    // original int9
  25. void    interrupt int_8(void);          // timer tick interrupt
  26. void    interrupt (*old_int8)(void);    // original int8
  27. void    interrupt int_28(void);         // DOS IDLE interrupt
  28. void    interrupt (*old_int28)(void);   // original int28
  29.  
  30. // non resident
  31. void    main(int, char **);
  32. void    tsr(unsigned size);             // dos call to tsr func.
  33. void    find_dos_active_flag(void);     // find flag location in memory
  34.  
  35. // resident
  36. void    start(void);                    // actual start of tsr
  37.  
  38. // Screen handling functions
  39. void    write_char(int x, int y, char ch, int attrib);
  40. void    write_string(int x, int y, char *str, int attrib);
  41. void    save_screen(char near *buffer);
  42. void    restore_screen(char near *buffer);
  43. void    wait_for_key(void);
  44.  
  45. // global variables
  46.  
  47. char    busy;                   // keep the tsr active only once at a time
  48. char    far *vid_mem;           // video memory pointer location
  49. unsigned vidbase;
  50. char    far *old_dta;           // keep the file data area for running program
  51. char    far *dos_active;        // make sure we don't interrupt dos
  52. char    screenbuffer[80*25*2];  // place where screen is saved
  53. int     interrupt_is_waiting;   // Tell int_8 to go in back door - 1=go
  54.  
  55. /**********************************************************************
  56. *                           MAIN                                      *
  57. **********************************************************************/
  58.  
  59. void main(int argc,char *argv[])
  60. {
  61. if(*argv[0]);                                   //trash a warning
  62.  
  63. if(argc==1)                                     // no arguments?
  64.     {                                       // assume color
  65.     vid_mem=(char far *)VIDEOMEMORY_COLOR;
  66.     vidbase=VIDEOBASE_COLOR;
  67.     }
  68. else                                            // any arguments at all?
  69.     {                                       // assume mono
  70.     vid_mem=(char far *)VIDEOMEMORY_MONO;
  71.     vidbase=VIDEOBASE_MONO;
  72.     }
  73.  
  74. interrupt_is_waiting=0;                 // not waiting on dos to run
  75.  
  76. find_dos_active_flag();
  77.  
  78. disable();                              // precautionary measure
  79.  
  80.                     // set up new interrupt vectors
  81. //setvect(0x05,int_5);                  // for print screen button
  82. old_int9 = getvect(0x09);
  83. setvect(0x09,int_9);                    // for key hit method
  84.  
  85. old_int8 = getvect(0x08);
  86. setvect(0x08,int_8);
  87. old_int28 = getvect(0x28);
  88. setvect(0x28,int_28);
  89. enable();
  90.  
  91. tsr(1000);                              // leave 16k resident (adjust as needed)
  92. }
  93.  
  94. /**********************************************************************
  95. *                             TSR                                     *
  96. **********************************************************************/
  97.  
  98. void tsr(unsigned size)                 // standard tsr bios call
  99. {
  100. union REGS r;
  101.  
  102. r.h.ah = 49;
  103. r.h.al = 0;
  104. r.x.dx = size;
  105. int86(0x21,&r, &r);                     // last line executed
  106. }                                       // never get to this line
  107.  
  108. /**********************************************************************
  109. *                            INT 5                                    *
  110. **********************************************************************/
  111.  
  112. void interrupt int_5(void)
  113. {
  114. if(!busy&&!*dos_active)                 // MUTEX around int5
  115.     {
  116.     busy = !busy;
  117.     start();
  118.     busy = !busy;
  119.     }
  120.  
  121. else if (*dos_active)                   // if dos is busy, let int 8
  122.     interrupt_is_waiting = 1;       // or int 28 run the program.
  123. }
  124.  
  125. /**********************************************************************
  126. *                            INT 9                                    *
  127. **********************************************************************/
  128.  
  129. void interrupt int_9(void)
  130. {
  131. char far *keybuf = (char far *) 1050;   // head pointer of keyboard
  132. int far *keybuffer = (int far *) 1050;
  133.  
  134. (*old_int9)();                          // use old keyboard routines first
  135.  
  136. if(*keybuf != *(keybuf+2))              // if buffer not empty
  137.     {
  138.     keybuf += *keybuf-30+5;         // go to character position
  139.     if (*keybuf==59)
  140.     // 59 = F1, 60 = F2, .... 68 = F10, 133= F11, 134=F12
  141.     // 84 = <Shift> F1, ... 93 = <shift> F10, 135=S-F11, 136=S-F12
  142.     // 94 = <ctrl F1> .... 103=<ctrl> F10, 137 = C-F11, 138=C-F12
  143.     // 104 = <alt F1> .... 113= <ctrl> F10, 139 = A-F11, 140=A-F12
  144.  
  145.         {
  146.         *(keybuffer+1)=*keybuffer;      // eat the key
  147.  
  148.         if(!busy&&!*dos_active)         // MUTEX around int9
  149.             {
  150.             busy = !busy;
  151.             start();
  152.             busy = !busy;
  153.             }
  154.  
  155.         else if (*dos_active)           // if dos is busy, let int 8
  156.             interrupt_is_waiting = 1;// or int 28 run the program.
  157.         }
  158.     }
  159. }
  160.  
  161. /**********************************************************************
  162. *                            INT 8                                    *
  163. **********************************************************************/
  164.  
  165. void    interrupt int_8(void)
  166. {
  167. (*old_int8)();
  168. if(!*dos_active&&!busy&&interrupt_is_waiting) // let it go in the back
  169.     {                               // door if we want it too
  170.     busy = !busy;
  171.     start();
  172.     busy = !busy;
  173.     }
  174. }
  175.  
  176. /**********************************************************************
  177. *                            INT 28                                   *
  178. **********************************************************************/
  179.  
  180. void    interrupt int_28(void)
  181. {
  182. (*old_int28)();
  183. if(!busy&&interrupt_is_waiting)         // The dos idle interrupt
  184.     {                               // method of trying to start
  185.     busy = !busy;                   // the tsr
  186.     start();
  187.     busy = !busy;
  188.     }
  189. }
  190.  
  191. /**********************************************************************
  192. *            FIND DOS ACTIVE FLAG                                     *
  193. **********************************************************************/
  194.  
  195. void find_dos_active_flag(void)         // undocumented dos call :-)
  196. {                                       // *dos_active = 1 when dos is
  197. union REGS r;                           // busy and 0 when dos is not busy
  198. struct SREGS s;
  199.  
  200. r.h.ah=0x34;
  201. int86x(0x21,&r, &r, &s);
  202. dos_active=(char far *)MK_FP(s.es,r.x.bx);
  203. }
  204.  
  205. /**********************************************************************
  206. *                         START                                       *
  207. **********************************************************************/
  208.  
  209. void start(void)
  210. {
  211. interrupt_is_waiting = 0;               // interrupt is now running
  212.  
  213.                 // needed if file operations in tsr
  214.                 // if you use these 2 lines you MUST
  215.                 // use compact, large, or huge model
  216.                 // <alt> options, compiler, code generation
  217. old_dta=getdta();               // save file data area of interrupted program
  218. setdta((char far *)MK_FP(_psp,0x80));   // set file area to the correct place
  219.  
  220. save_screen(screenbuffer);
  221.  
  222. //
  223. //
  224. //
  225. // put your program here
  226.  
  227. write_string(10,10,"TSR ACTIVATED",0x0F);
  228.  
  229. //
  230. //
  231. //
  232.  
  233. wait_for_key();
  234.  
  235. restore_screen(screenbuffer);
  236.                 // needed if file operations in trs
  237. setdta(old_dta);                // set file data area back to what it was
  238. }
  239.  
  240.  
  241. /**********************************************************************
  242. *                   WAIT FOR KEY                                      *
  243. **********************************************************************/
  244.  
  245. // This function waits for a key press to occur.  Kind of like DOS pause
  246. // note that this doesn't work right is dos EDIT, QBASIC, or DOSSHELL
  247. // the problem is that it takes about 8 key hits or so for those programs
  248. // to notice the key hit, and then the keys pressed aren't eaten.
  249.  
  250. void wait_for_key(void)
  251. {
  252. int key_hit;
  253. int far *t2 = (int far *) 1050;         // keyboard buffer area
  254. char far *t = (char far *) 1050;        // keyboard buffer area
  255.  
  256. key_hit = 0;                            // no key hit yet
  257.  
  258. enable();
  259. while(!key_hit)
  260.     {
  261.     key_hit = *t - *(t+2);          // is keyboard buffer empty?
  262.     }
  263. disable();
  264.  
  265. *(t2+1) = *t2;                  // eat the key press
  266. }
  267.  
  268. /**********************************************************************
  269. *                        WRITE CHAR                                   *
  270. **********************************************************************/
  271.  
  272. // note that x and y are 0 based.  attrib 0x07 is dos gray or use colors
  273. // in conio.h
  274.  
  275. void write_char(int x, int y, char ch, int attrib)
  276. {
  277. char far *v;
  278.  
  279. v = vid_mem;
  280. v += y*160 + x*2;
  281. *v++ = ch;
  282. *v = attrib;
  283. }
  284.  
  285. /**********************************************************************
  286. *                         WRITE STRING                                *
  287. **********************************************************************/
  288.  
  289. // note that x and y are 0 based.  attrib 0x07 is dos gray or use colors
  290. // in conio.h
  291.  
  292. void write_string(int x, int y, char *str, int attrib)
  293. {
  294. for( ; *str; str++,x++)
  295.     write_char(x, y, *str, attrib);
  296. }
  297.  
  298. /**********************************************************************
  299. *                   SAVE SCREEN                                       *
  300. **********************************************************************/
  301.  
  302. /* saves the contents of the color screen in buffer */
  303. void save_screen(char near *buffer)
  304. {
  305. movedata(vidbase, 0, _DS, (unsigned)buffer, 80*25*2);
  306. }
  307.  
  308. /**********************************************************************
  309. *                   RESTORE SCREEN                                    *
  310. **********************************************************************/
  311.  
  312. /* restores the contents of the mono screen in buffer */
  313. void restore_screen(char near *buffer)
  314. {
  315. movedata(_DS, (unsigned)buffer, vidbase, 0, 80*25*2);
  316. }
  317.  
  318. /**********************************************************************
  319. *                   READ FILE                                         *
  320. **********************************************************************/
  321.  
  322. // to use this function, you must use the setdta() and getdta() functions
  323. // in start().
  324.  
  325. int read_file()
  326. {
  327. int     fd;
  328. char    input[50];
  329.  
  330. if((fd =_open("c:\\temp\\temp.in",O_RDONLY))<0) // open the file
  331.     {
  332.     write_string(3, 3, "OOPS--can't open the file", 0x8F);
  333.     return(-1);                             // return failure
  334.     }
  335.  
  336. lseek (fd,0,SEEK_SET);                          // rewind to start of file
  337.                         // (optional)
  338. if((_read(fd,input,49))<0)                      // handle, string, #bytes
  339.     write_string(3,10,"OOPS--read error1",0x8F);
  340.  
  341. input[49]=0;                                    // null terminate
  342.  
  343. _close(fd);                                     // close the file
  344.  
  345. return (0);                                     // return success
  346. }
  347.  
  348. /**********************************************************************
  349. *                WRITE FILE                                           *
  350. **********************************************************************/
  351.  
  352. // to use this function, you must use the setdta() and getdta() functions
  353. // in start().
  354.  
  355. int write_file(void)
  356. {
  357. int fd;
  358. char cr=0x0D, lf=0x0A;
  359.  
  360. if((fd =_open("c:\\temp\\temp.out",O_WRONLY))<0)
  361.     if((fd =_creat("c:\\temp\\temp.out",_A_NORMAL))<0)
  362.         {
  363.         write_string(3,10,"OOPS--write error1",0x8F);
  364.         return (-1);
  365.         }
  366.  
  367. lseek (fd,0,SEEK_END);                          // jump to end of file
  368.  
  369. if(_write (fd,"HELLO THERE",strlen("HELLO THERE"))==-1)
  370.     {
  371.     write_string(3,1,"OOPS--write error1",0x8F);
  372.     return (-1);
  373.     }
  374. if(_write (fd,&cr,1)==-1)
  375.     write_string(3,2,"OOPS--write error2",0x8F);
  376.  
  377. if(_write (fd,&lf,1)==-1)
  378.     write_string(3,3,"OOPS--write error3",0x8F);
  379.  
  380. _close(fd);                                     // close the file
  381.  
  382. return (0);                                     // return success
  383. }
  384.